package shamir;

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;

import util.Utils;

public class shamirGenerator
{
    private shamirKey[] generatedShamirKeys;
    private final static int n = 5; // number of generated shares
    private final static int t = 3; // number of shares for solve the secret (t
                                    // <= n)
    private int numBits; // number of bits of p
    private String privKeyPath; // path for private keys-first part
    private String pubKeyPath;
    private String[] privKeyFileNames;// tab of priv file names (enumerated)

    public shamirGenerator( String privKeyPath, String pubKeyPath )
    {
        this.privKeyPath = privKeyPath;
        this.pubKeyPath = pubKeyPath;
        privKeyFileNames = createFileNames( privKeyPath );
    }

    private String[] createFileNames( String privOutput ) // enumerate paths for
                                                          // priv keys
    {
        String[] privOutTab = new String[ n ];
        for( int i = 0; i < n; i++ )
            privOutTab[ i ] = privOutput.concat( Integer.toString( i ) ).concat( ".txt" );
        return privOutTab;
    }

    private void divideShamir( String secret, String[] tab, int t ) // creating
                                                                    // and
                                                                    // dividing
                                                                    // priv key
    {
        BigInteger nB = new BigInteger( secret.getBytes() );
        numBits = nB.bitLength() + 1;
        // System.out.println( "Secret before = " + secret );
        // Create key
        BigInteger[] s;
        try
        {
            s = shamir.generateParameters( t, numBits, secret.getBytes() );
        }
        catch( shamirException sE )
        {
            System.err.println( "Error while generate shamir keys 1" );
            return;
        }
        // System.out.println("parameters generated");
        try
        {
            generatedShamirKeys = shamir.generateKeys( n, t, numBits, s );
        }
        catch( shamirException sE )
        {
            System.err.println( "Error while generate shamir keys 2" );
            return;
        }
        for( int i = 0; i < n; i++ )
            try
            {
                Utils.saveShamirKey( tab[ i ], generatedShamirKeys[ i ] );
            }
            catch( Exception e )
            {
                System.err.println( "error while saving" );
            }
    }

    public void generate()// generating pair of keys, dividing priv
    {
        try
        {
            KeyPairGenerator kpg = KeyPairGenerator.getInstance( "RSA" );
            kpg.initialize( 1024 );
            KeyPair kp = kpg.genKeyPair();
            KeyFactory fact = KeyFactory.getInstance( "RSA" );
            RSAPublicKeySpec pub = fact.getKeySpec( kp.getPublic(), RSAPublicKeySpec.class );
            RSAPrivateKeySpec priv = fact.getKeySpec( kp.getPrivate(), RSAPrivateKeySpec.class );
            divideShamir( priv.getPrivateExponent().toString(), privKeyFileNames, t );
            Utils.saveToFile( pubKeyPath, pub.getModulus(), pub.getPublicExponent() );
        }
        catch( Exception e )
        {
            e.printStackTrace();
            System.err.println( "Invalid input" );
        }
    }
    /**
     * <p>
     * Calculate Shamir scheme. You need t shares of n for resolve the secret
     * </p>
     */
}
